﻿Imports Newtonsoft.Json.Linq

Public Class QueryParser

    Private jsonString As String


    Public Sub New(ByVal jsonString As String)
        Me.jsonString = jsonString
    End Sub

    ''' <summary>
    ''' Helper function for all Query Objects. This must be called before all queries are parsed.
    ''' It preprocesses them to make sure they are able to be parsed by the Newtonsoft.Json libaray
    ''' </summary>
    ''' <returns>a json object processed.</returns>
    ''' <remarks></remarks>
    Public Function GetQueryObject() As JObject
        Dim jsonObject As JObject

        jsonString = jsonString.Replace(vbCrLf, "")

        If Not jsonString.Contains("@u") Then
            jsonString = "{""@u"":" + jsonString + "}"
        End If

        If String.Compare(jsonString.Substring(jsonString.Length - 2, 2), "}}") = 0 Then
            jsonString = jsonString.Remove(jsonString.Length - 1)
        End If

        If String.Compare(jsonString.Substring(0, 2), "{{") = 0 Then
            jsonString = jsonString.Remove(0, 1)
        End If

        Try
            jsonObject = JObject.Parse(jsonString)
        Catch ex As Exception

            jsonObject = New JObject
        End Try
        Return jsonObject


    End Function


    ''' <summary>
    ''' This gets a queueID of a building from the jsonObject returned from sendign a build request
    ''' </summary>
    ''' <returns>The building ID that is to be canceled.</returns>
    ''' <remarks></remarks>
    Public Function GetQueueID(ByVal TextBoxBuildingID As String) As String
        Dim jsonObj As JToken
        Dim buildingID As String
        Dim i As Integer
        Dim jsonquery As String
        Dim queueid As String

        jsonObj = GetQueryObject()

        If Not validQuery() Then
            Return ""
        End If


        Try
            i = jsonObj.SelectToken("@u.CITY.q").Count - 1
        Catch ex As Exception
            Return ""
        End Try

        While i >= 0
            jsonquery = "@u.CITY.q[" + CStr(i) + "].b"
            buildingID = jsonObj.SelectToken(jsonquery).ToString
            If String.Compare(buildingID, TextBoxBuildingID) = 0 Then
                jsonquery = "@u.CITY.q[" + CStr(i) + "].i"
                queueid = jsonObj.SelectToken(jsonquery).ToString()
                Return queueid

            End If
            i = i - 1
        End While
        Return ""
    End Function

    ''' <summary>
    ''' Parses json Object to get the names and ids of all cities for a specific Session ID
    ''' </summary>
    ''' <remarks></remarks>
    Public Function setCityDropDownList(ByVal dict As Dictionary(Of String, String)) As Boolean
        Dim jsonObject As JToken
        Dim buildingID As String
        Dim buildingName As String
        Dim i As Integer

        jsonObject = GetQueryObject()

        If Not validQuery() Then
            Return False
        End If


        While i < jsonObject.SelectToken("@u[1].D.c").Count
            buildingName = jsonObject.SelectToken("@u[1].D.c[" + CStr(i) + "].n").ToString
            buildingID = jsonObject.SelectToken("@u[1].D.c[" + CStr(i) + "].i").ToString
            If Not dict.ContainsKey(buildingName) Then
                dict.Add(buildingName, buildingID)
            End If
            i = i + 1
        End While
        Return True
    End Function

    ''' <summary>
    ''' Parses a json Object and makes a CityClass object with the number of resources a city is missing.
    ''' The city object contains it's City ID
    ''' </summary>
    ''' <returns>A cityClass object</returns>
    ''' <remarks></remarks>
    Public Function GetCityObject(ByVal cityID As String) As CityClass
        Dim jsonObject As JToken
        Dim resourceAmount As String
        Dim resourceMax As String
        Dim resourcesNeeded As Integer
        Dim maxMinResources As Integer = 0
        Dim i As Integer
        Dim city As New CityClass(cityID)

        jsonObject = GetQueryObject()

        If Not validQuery() Then
            Return city
            Exit Function
        End If


        While i < jsonObject.SelectToken("@u[1].D.r").Count
            resourceAmount = jsonObject.SelectToken("@u[1].D.r[" + CStr(i) + "].b").ToString
            resourceMax = jsonObject.SelectToken("@u[1].D.r[" + CStr(i) + "].m").ToString
            resourcesNeeded = CInt(resourceMax) - CInt(resourceAmount) - 2000
            If maxMinResources < 1 Or resourceAmount < maxMinResources Then
                maxMinResources = resourceAmount
            End If

            i = i + 1
            city.maxRes = maxMinResources - 4000
            city.Resources.Add(CInt(resourcesNeeded / 1000))
        End While


        Try
            city.queueID1 = jsonObject.SelectToken("@u[1].D.uq[0].i").ToString
            city.queueID2 = jsonObject.SelectToken("@u[1].D.uq[1].i").ToString
            city.recruitCount = jsonObject.SelectToken("@u[1].D.uq[0].l").ToString
            city.recruitSpeed = jsonObject.SelectToken("@u[1].D.uq[1].es").ToString - jsonObject.SelectToken("@u[1].D.uq[1].ss").ToString
        Catch ex As Exception

        End Try

        GetCityObject = city
    End Function

    ''' <summary>
    ''' Returns an array of all possible research.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getResearchTitles(ByVal researchList As Dictionary(Of String, ResearchClass)) As String
        Dim jsonObject As JObject
        Dim jsonNode As JProperty
        Dim jsonNode1 As JObject
        Dim title As String
        Dim startID As String
        Dim nextID As String
        Dim labelList As List(Of String)
        Dim i As Integer
        'Dim j As Integer


        jsonObject = JObject.Parse(jsonString)
        jsonNode = CType(jsonObject.SelectToken("techTrees").First, JProperty)

        While i < jsonObject.SelectToken("techTrees").Count
            labelList = New List(Of String)

            title = jsonObject.SelectToken("techTrees." & jsonNode.Name & ".n").ToString
            startID = jsonObject.SelectToken("techTrees." & jsonNode.Name & ".tts").ToString
            nextID = startID


            While Not String.Equals(nextID, "0")

                jsonNode1 = CType(jsonObject.SelectToken("techTreeSteps." & nextID), JObject)
                labelList.Add(nextID)
                nextID = jsonNode1.SelectToken("c").ToString
                jsonNode1.RemoveAll()
            End While

            researchList.Add(title, New ResearchClass(title, startID, labelList))
            jsonNode = CType(jsonNode.Next, JProperty)
            i = i + 1
        End While
        Return "true"
    End Function

    Public Function validQuery() As Boolean
        Dim jsonObject As JObject
        Dim errorString As String = ""
        Dim i As Integer = 0
        jsonObject = GetQueryObject()

        While i < jsonObject.SelectToken("@u").Count
            Try
                errorString = jsonObject.SelectToken("@u[" & i & "].D").ToString()
            Catch
                Return True
            End Try
            If String.Compare(errorString, "CLOSED") = 0 Or String.Compare(errorString, "KICKED") = 0 Then
                Return False
            End If
            i = i + 1
        End While

        Return True
    End Function

End Class
